#ifndef IPV4_HPP_
	#define IPV4_HPP_


	#define IPV4_VERSION       		4		//!< Версия протокола IP
	#define IPV4_HEAD_SIZE     		20		//!< Размер IP заголовка в байтах


	enum ip_protocol_e
	{
		ICMP	= 1,			//!< Internet Control Message Protocol
//		TCP		= 6,			//!< Transmission Control Protocol
		UDP		= 17			//!< User Datagram Protocol
	};


	//! @brief 				Метод позволяет задать ip источника
	/*!	@param		ip		Адрес текущего устройства
	 *  @return	0
	 */
	alt_u8 ipv4_set_source_ip(alt_u32 ip);

	//! @brief 				Метод позволяет задать ip назначения
	/*!	@param		ip		Адрес устройства источника
	 *  @return		0
	 */
	alt_u8 ipv4_set_destination_ip(alt_u32 ip);

	//! @brief 				Разбор указанного пакета
	/*!	@param		header	Адрес начала пакета (без преамбулы)
	 *  @return		0
	 */
	alt_u8 ipv4_header_parser(alt_u8* header);

	//! @brief 					Метод формирует заголовок ip по заданному адресу
	/*!	@param		header		Начало заголовка
	 *	@param		data_size	Размер поля полезных данных
	 *  @return		0
	 */
	alt_u8 ipv4_create_head(alt_u8* header, alt_u16 data_size);

	//! @brief 				Функция для расчета контрольной суммы заголовка
	/*!	@param		sum		Исходное значение
	 *  @param		buf		Буфер с данными
	 *  @param		len		Количество данных
	 *  @return		chksm   Контрольная сумма
	 */
	alt_u16 ipv4_checksum(alt_u32 sum, alt_u8 *buf, alt_u16 len);

	//! @brief 				Получить указатель на поле данных и размер поля
	/*!	@param		data
	 * 	@param		size
	 *  @return		0
	 */
	alt_u8 ipv4_get_payload(alt_u32* ofst, alt_u16* size);


	//! @brief 				Получить протокол обработанного пакета
	/*!	@param				нет
	 *  @return		prot    Протокол
	 */
	alt_u16 ipv4_get_protocol();

	//! @brief 				Установить протокол формируемого пакета
	/*!	@param				нет
	 *  @return		prot    Протокол
	 */
	alt_u8 ipv4_set_protocol(alt_u16 prot);


	//! @brief 				Получить протокол обработанного пакета
	/*!	@param				нет
	 *  @return		ip      IP источника последнего пакета
	 */
	alt_u32 ipv4_get_source_ip();

	//! Структура заголовка IP
	union	ipv4_header_u
	{
		struct __attribute__((packed, aligned(1)))
		{
			unsigned 	ihl				:4;		//!< Размер заголовка в 32-битных словах
			unsigned 	version			:4;		//!< Версия протокола
			//tos_t	tos;					//!< Type of Service
			unsigned 	tos				:8;		//!< Type of Service
			unsigned 	length			:16;	//!< Длина пакета
			unsigned 	identification	:16;	//!< Идентификатор

			unsigned 	flags			:3;		//!< Флаги
			unsigned 	offset			:13;	//!< Смещение фрагмента

			unsigned 	ttl				:8;		//!< Время жизни
			unsigned 	protocol		:8;		//!< Протокол данных пакета
			unsigned 	head_checksumm	:16;	//!< Контрольная сумма заголовка
			alt_u32		s_ip;					//!< Адрес источника
			alt_u32		d_ip;					//!< Адрес назначения
		};
		alt_u8			data[IPV4_HEAD_SIZE];
	};

	/*
	typedef struct	dscp_s
	{
		alt_u8 prior		:3;			//!< Приоритет
		alt_u8 d			:1;			//!< Требование ко времени задержки
		alt_u8 t			:1;			//!< Требование к пропускной способности
		alt_u8 r			:1;			//!< Требование к надежности
	} dscp_t;

	typedef struct	tos_s
	{
		dscp_t	dscp;					//!< DiffServ Code Point
		alt_u8 	ecn			:2;			//!< Explicit Congestion Notification.
	} tos_t;
	*/

	//! Тип заголовка пакетов ip
	typedef union ipv4_header_u 	ipv4_header_t;




#endif /* IPV4_HPP_ */
